From a2b894c4a4a7239481d89cea41a0116b954628e2 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Thu, 20 Feb 2020 07:53:15 -0700 Subject: [PATCH] use initializer list to construct gpx tag hash. (#509) --- gpx.cc | 80 ++++++--------- gpx.h | 301 ++++++++++++++++++++++++++++----------------------------- 2 files changed, 181 insertions(+), 200 deletions(-) diff --git a/gpx.cc b/gpx.cc index c2b503314..108475425 100644 --- a/gpx.cc +++ b/gpx.cc @@ -70,12 +70,12 @@ GpxFormat::gpx_add_to_global(QStringList& ge, const QString& s) // Temporarily mock the old GPX writer's hardcoded fixed length for float/double // types. This can be removed once we have time/interest in regenerating all our // zillion reference files. -inline QString GpxFormat::toString(double d) +inline QString GpxFormat::toString(double d) const { return QString::number(d, 'f', 9); } -inline QString GpxFormat::toString(float f) +inline QString GpxFormat::toString(float f) const { return QString::number(f, 'f', 6); } @@ -102,7 +102,7 @@ GpxFormat::gpx_reset_short_handle() } void -GpxFormat::gpx_write_gdata(const QStringList& ge, const QString& tag) +GpxFormat::gpx_write_gdata(const QStringList& ge, const QString& tag) const { if (!ge.isEmpty()) { writer->writeStartElement(tag); @@ -123,24 +123,11 @@ GpxFormat::gpx_write_gdata(const QStringList& ge, const QString& tag) } } -GpxFormat::tag_type -GpxFormat::get_tag(const QString& t, int* passthrough) +GpxFormat::tag_mapping +GpxFormat::get_tag(const QString& t) const { - tag_mapping* tm = hash[t]; - if (tm) { - *passthrough = tm->tag_passthrough; - return tm->tag_type_; - } - *passthrough = 1; - return tt_unknown; -} - -void -GpxFormat::prescan_tags() -{ - for (tag_mapping* tm = tag_path_map; tm->tag_type_ != 0; tm++) { - hash[tm->tag_name] = tm; - } + // returns default constructed value if key not found. + return hash.value(t); } void @@ -201,7 +188,7 @@ GpxFormat::tag_cache_desc(const QXmlStreamAttributes& attr) } void -GpxFormat::tag_gs_cache(const QXmlStreamAttributes& attr) +GpxFormat::tag_gs_cache(const QXmlStreamAttributes& attr) const { geocache_data* gc_data = wpt_tmp->AllocGCData(); @@ -240,7 +227,7 @@ GpxFormat::start_something_else(const QString& el, const QXmlStreamAttributes& a * It was found to be faster to append one element at a time compared to * a) assiging new_tag->attributes = attr, or * b) appending in one step, new_tag.attributes.apppend(attr) - * Tested with on ubuntu bioinic with Qt 5.9.5 and a large Geocache file + * Tested with on ubuntu bionic with Qt 5.9.5 and a large Geocache file * generated by Groundspeak. */ for (const auto& a : attr) { @@ -293,7 +280,7 @@ GpxFormat::end_something_else() } void -GpxFormat::tag_log_wpt(const QXmlStreamAttributes& attr) +GpxFormat::tag_log_wpt(const QXmlStreamAttributes& attr) const { /* create a new waypoint */ auto* lwp_tmp = new Waypoint; @@ -322,15 +309,13 @@ GpxFormat::tag_log_wpt(const QXmlStreamAttributes& attr) void GpxFormat::gpx_start(const QString& el, const QXmlStreamAttributes& attr) { - int passthrough; - /* * Reset end-of-string without actually emptying/reallocing cdatastr. */ cdatastr = QString(); - int tag = get_tag(current_tag, &passthrough); - switch (tag) { + tag_mapping tag = get_tag(current_tag); + switch (tag.type) { case tt_gpx: tag_gpx(attr); break; @@ -397,7 +382,7 @@ GpxFormat::gpx_start(const QString& el, const QXmlStreamAttributes& attr) default: break; } - if (passthrough) { + if (tag.passthrough) { start_something_else(el, attr); } } @@ -567,15 +552,14 @@ xml_parse_time(const QString& dateTimeString) void GpxFormat::gpx_end(const QString& /*unused*/) { - int passthrough; static QDateTime gc_log_date; // Remove leading, trailing whitespace. cdatastr = cdatastr.trimmed(); - tag_type tag = get_tag(current_tag, &passthrough); + tag_mapping tag = get_tag(current_tag); - switch (tag) { + switch (tag.type) { /* * First, the tags that are file-global. */ @@ -698,7 +682,7 @@ GpxFormat::gpx_end(const QString& /*unused*/) case tt_garmin_wpt_country: case tt_garmin_wpt_postal_code: case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastr, wpt_tmp); + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag.type, cdatastr, wpt_tmp); break; /* @@ -898,7 +882,7 @@ GpxFormat::gpx_end(const QString& /*unused*/) break; } - if (passthrough) { + if (tag.passthrough) { end_something_else(); } @@ -936,8 +920,6 @@ GpxFormat::rd_init(const QString& fname) current_tag.clear(); - prescan_tags(); - cdatastr = QString(); if (nullptr == gpx_global) { @@ -1151,7 +1133,7 @@ GpxFormat::read() } void -GpxFormat::write_attributes(const QXmlStreamAttributes& attributes) +GpxFormat::write_attributes(const QXmlStreamAttributes& attributes) const { for (const auto& attribute : attributes) { writer->writeAttribute(attribute.qualifiedName().toString(), attribute.value().toString()); @@ -1159,7 +1141,7 @@ GpxFormat::write_attributes(const QXmlStreamAttributes& attributes) } void -GpxFormat::fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) +GpxFormat::fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) const { while (tag) { writer->writeStartElement(tag->tagname); @@ -1194,7 +1176,7 @@ GpxFormat::fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links. */ void -GpxFormat::write_gpx_url(const UrlList& urls) +GpxFormat::write_gpx_url(const UrlList& urls) const { if (gpx_write_version > gpx_1_0) { for (const auto& l : urls) { @@ -1216,7 +1198,7 @@ GpxFormat::write_gpx_url(const UrlList& urls) } void -GpxFormat::write_gpx_url(const Waypoint* waypointp) +GpxFormat::write_gpx_url(const Waypoint* waypointp) const { if (waypointp->HasUrlLink()) { write_gpx_url(waypointp->urls); @@ -1224,7 +1206,7 @@ GpxFormat::write_gpx_url(const Waypoint* waypointp) } void -GpxFormat::write_gpx_url(const route_head* rh) +GpxFormat::write_gpx_url(const route_head* rh) const { if (rh->rte_urls.HasUrlLink()) { write_gpx_url(rh->rte_urls); @@ -1237,7 +1219,7 @@ GpxFormat::write_gpx_url(const route_head* rh) * Order counts. */ void -GpxFormat::gpx_write_common_acc(const Waypoint* waypointp) +GpxFormat::gpx_write_common_acc(const Waypoint* waypointp) const { const char* fix = nullptr; @@ -1284,7 +1266,7 @@ GpxFormat::gpx_write_common_acc(const Waypoint* waypointp) void -GpxFormat::gpx_write_common_position(const Waypoint* waypointp, const gpx_point_type point_type) +GpxFormat::gpx_write_common_position(const Waypoint* waypointp, const gpx_point_type point_type) const { if (waypointp->altitude != unknown_alt) { writer->writeTextElement(QStringLiteral("ele"), QString::number(waypointp->altitude, 'f', elevation_precision)); @@ -1307,7 +1289,7 @@ GpxFormat::gpx_write_common_position(const Waypoint* waypointp, const gpx_point_ } void -GpxFormat::gpx_write_common_extensions(const Waypoint* waypointp, const gpx_point_type point_type) +GpxFormat::gpx_write_common_extensions(const Waypoint* waypointp, const gpx_point_type point_type) const { // gpx version we are writing is >= 1.1. if ((opt_humminbirdext && (WAYPT_HAS(waypointp, depth) || WAYPT_HAS(waypointp, temperature))) || @@ -1375,7 +1357,7 @@ GpxFormat::gpx_write_common_extensions(const Waypoint* waypointp, const gpx_poin } void -GpxFormat::gpx_write_common_description(const Waypoint* waypointp, const QString& oname) +GpxFormat::gpx_write_common_description(const Waypoint* waypointp, const QString& oname) const { writer->writeOptionalTextElement(QStringLiteral("name"), oname); @@ -1392,7 +1374,7 @@ GpxFormat::gpx_write_common_description(const Waypoint* waypointp, const QString } void -GpxFormat::gpx_waypt_pr(const Waypoint* waypointp) +GpxFormat::gpx_waypt_pr(const Waypoint* waypointp) const { writer->writeStartElement(QStringLiteral("wpt")); writer->writeAttribute(QStringLiteral("lat"), toString(waypointp->latitude)); @@ -1460,7 +1442,7 @@ GpxFormat::gpx_track_hdr(const route_head* rte) } void -GpxFormat::gpx_track_disp(const Waypoint* waypointp) +GpxFormat::gpx_track_disp(const Waypoint* waypointp) const { bool first_in_trk = waypointp == current_trk_head->waypoint_list.front(); @@ -1524,7 +1506,7 @@ GpxFormat::gpx_track_pr() } void -GpxFormat::gpx_route_hdr(const route_head* rte) +GpxFormat::gpx_route_hdr(const route_head* rte) const { writer->writeStartElement(QStringLiteral("rte")); writer->writeOptionalTextElement(QStringLiteral("name"), rte->rte_name); @@ -1560,7 +1542,7 @@ GpxFormat::gpx_route_hdr(const route_head* rte) } void -GpxFormat::gpx_route_disp(const Waypoint* waypointp) +GpxFormat::gpx_route_disp(const Waypoint* waypointp) const { writer->writeStartElement(QStringLiteral("rtept")); writer->writeAttribute(QStringLiteral("lat"), toString(waypointp->latitude)); @@ -1585,7 +1567,7 @@ GpxFormat::gpx_route_disp(const Waypoint* waypointp) } void -GpxFormat::gpx_route_tlr(const route_head* /*unused*/) +GpxFormat::gpx_route_tlr(const route_head* /*unused*/) const { writer->writeEndElement(); // Close rte tag. } diff --git a/gpx.h b/gpx.h index ab5036586..f1b15685d 100644 --- a/gpx.h +++ b/gpx.h @@ -181,41 +181,50 @@ private: tt_humminbird_trk_trkseg_trkpt_depth, }; + struct tag_mapping { +#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */ + /* avoid MSVC 2015 C2664 errors. */ + tag_mapping() = default; + tag_mapping(tag_type t, bool p) : type(t),passthrough(p) {} +#endif + tag_type type{tt_unknown}; /* enum from above for this tag */ + bool passthrough{true}; /* true if we don't generate this */ + }; + - void gpx_add_to_global(QStringList& ge, const QString& s); - inline QString toString(double d); - inline QString toString(float f); + static void gpx_add_to_global(QStringList& ge, const QString& s); + inline QString toString(double d) const; + inline QString toString(float f) const; void gpx_reset_short_handle(); - void gpx_write_gdata(const QStringList& ge, const QString& tag); - tag_type get_tag(const QString& t, int* passthrough); - void prescan_tags(); + void gpx_write_gdata(const QStringList& ge, const QString& tag) const; + tag_mapping get_tag(const QString& t) const; void tag_gpx(const QXmlStreamAttributes& attr); void tag_wpt(const QXmlStreamAttributes& attr); void tag_cache_desc(const QXmlStreamAttributes& attr); - void tag_gs_cache(const QXmlStreamAttributes& attr); + void tag_gs_cache(const QXmlStreamAttributes& attr) const; void start_something_else(const QString& el, const QXmlStreamAttributes& attr); void end_something_else(); - void tag_log_wpt(const QXmlStreamAttributes& attr); + void tag_log_wpt(const QXmlStreamAttributes& attr) const; void gpx_start(const QString& el, const QXmlStreamAttributes& attr); void gpx_end(const QString& unused); void gpx_cdata(const QString& s); - void write_attributes(const QXmlStreamAttributes& attributes); - void fprint_xml_chain(xml_tag* tag, const Waypoint* wpt); - void write_gpx_url(const UrlList& urls); - void write_gpx_url(const Waypoint* waypointp); - void write_gpx_url(const route_head* rh); - void gpx_write_common_acc(const Waypoint* waypointp); - void gpx_write_common_position(const Waypoint* waypointp, gpx_point_type point_type); - void gpx_write_common_extensions(const Waypoint* waypointp, gpx_point_type point_type); - void gpx_write_common_description(const Waypoint* waypointp, const QString& oname); - void gpx_waypt_pr(const Waypoint* waypointp); + void write_attributes(const QXmlStreamAttributes& attributes) const; + void fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) const; + void write_gpx_url(const UrlList& urls) const; + void write_gpx_url(const Waypoint* waypointp) const; + void write_gpx_url(const route_head* rh) const; + void gpx_write_common_acc(const Waypoint* waypointp) const; + void gpx_write_common_position(const Waypoint* waypointp, gpx_point_type point_type) const; + void gpx_write_common_extensions(const Waypoint* waypointp, gpx_point_type point_type) const; + void gpx_write_common_description(const Waypoint* waypointp, const QString& oname) const; + void gpx_waypt_pr(const Waypoint* waypointp) const; void gpx_track_hdr(const route_head* rte); - void gpx_track_disp(const Waypoint* waypointp); + void gpx_track_disp(const Waypoint* waypointp) const; void gpx_track_tlr(const route_head* unused); void gpx_track_pr(); - void gpx_route_hdr(const route_head* rte); - void gpx_route_disp(const Waypoint* waypointp); - void gpx_route_tlr(const route_head* unused); + void gpx_route_hdr(const route_head* rte) const; + void gpx_route_disp(const Waypoint* waypointp) const; + void gpx_route_tlr(const route_head* unused) const; void gpx_route_pr(); void gpx_waypt_bound_calc(const Waypoint* waypointp); void gpx_write_bounds(); @@ -289,12 +298,6 @@ private: }; GpxGlobal* gpx_global = nullptr; - struct tag_mapping { - tag_type tag_type_; /* enum from above for this tag */ - int tag_passthrough; /* true if we don't generate this */ - const char* tag_name; /* xpath-ish tag name */ - }; - /* * xpath(ish) mappings between full tag paths and internal identifiers. * These appear in the order they appear in the GPX specification. @@ -303,29 +306,18 @@ private: /* /gpx/ for GPX 1.0, /gpx/metadata/ for GPX 1.1 */ #define METATAG(type,name) \ - {type, 0, "/gpx/" name}, \ - {type, 0, "/gpx/metadata/" name} - - tag_mapping tag_path_map[158] = { - { tt_gpx, 0, "/gpx" }, - METATAG(tt_name, "name"), - METATAG(tt_desc, "desc"), - { tt_author, 0, "/gpx/author" }, - { tt_email, 0, "/gpx/email" }, - { tt_url, 0, "/gpx/url" }, - { tt_urlname, 0, "/gpx/urlname" }, - METATAG(tt_keywords, "keywords"), - { tt_link, 0, "/gpx/metadata/link" }, - { tt_link_text, 0, "/gpx/metadata/link/text" }, - { tt_link_type, 0, "/gpx/metadata/link/type" }, - - { tt_wpt, 0, "/gpx/wpt" }, + {"/gpx/" name, {type, false}}, \ + {"/gpx/metadata/" name, {type, false}} - /* Double up the GPX 1.0 and GPX 1.1 styles */ #define GEOTAG(type,name) \ - {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name }, \ - {type, 1, "/gpx/wpt/extensions/cache/" name }, \ - {type, 1, "/gpx/wpt/geocache/" name } /* opencaching.de */ + {"/gpx/wpt/groundspeak:cache/groundspeak:" name, {type, true}}, \ + {"/gpx/wpt/extensions/cache/" name, {type, true}}, \ + {"/gpx/wpt/geocache/" name, {type, true}} /* opencaching.de */ + +#define GPXWPTTYPETAG(name,type,passthrough) \ + {"/gpx/wpt/" name, {type, passthrough}}, \ + {"/gpx/trk/trkseg/trkpt/" name, {type, passthrough}}, \ + {"/gpx/rte/rtept/" name, {type, passthrough}} #define GARMIN_RTE_EXT "/gpx/rte/extensions/gpxx:RouteExtension" #define GARMIN_TRK_EXT "/gpx/trk/extensions/gpxx:TrackExtension" @@ -333,114 +325,121 @@ private: #define GARMIN_TRKPT_EXT "/gpx/trk/trkseg/trkpt/extensions/gpxtpx:TrackPointExtension" #define GARMIN_RTEPT_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension" -// GEOTAG( tt_cache, "cache"), - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - - GEOTAG(tt_cache_name, "name"), - GEOTAG(tt_cache_container, "container"), - GEOTAG(tt_cache_type, "type"), - GEOTAG(tt_cache_difficulty, "difficulty"), - GEOTAG(tt_cache_terrain, "terrain"), - GEOTAG(tt_cache_hint, "encoded_hints"), - GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ - GEOTAG(tt_cache_desc_short, "short_description"), - GEOTAG(tt_cache_desc_long, "long_description"), - GEOTAG(tt_cache_placer, "owner"), - GEOTAG(tt_cache_favorite_points, "favorite_points"), - GEOTAG(tt_cache_personal_note, "personal_note"), - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, - { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, - { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, - { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, - - { tt_wpt_extensions, 0, "/gpx/wpt/extensions" }, - - { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT }, - { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity" }, - { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature" }, - { tt_garmin_wpt_temperature, 1, GARMIN_TRKPT_EXT "/gpxtpx:atemp" }, - { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth" }, - { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode" }, - { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories" }, - { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category" }, - { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress" }, - { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City" }, - { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State" }, - { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country" }, - { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode" }, - { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber"}, +// Maintain a fast mapping from full tag names to the struct above. + const QHash hash = { + {"/gpx", {tt_gpx, false}}, + METATAG(tt_name, "name"), + METATAG(tt_desc, "desc"), + {"/gpx/author", {tt_author, false}}, + {"/gpx/email", {tt_email, false}}, + {"/gpx/url", {tt_url, false}}, + {"/gpx/urlname", {tt_urlname, false}}, + METATAG(tt_keywords, "keywords"), + {"/gpx/metadata/link", {tt_link, false}}, + {"/gpx/metadata/link/text", {tt_link_text, false}}, + {"/gpx/metadata/link/type", {tt_link_type, false}}, + + {"/gpx/wpt", {tt_wpt, false}}, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ +// GEOTAG(tt_cache, "cache"), + {"/gpx/wpt/groundspeak:cache", {tt_cache, true}}, + + GEOTAG(tt_cache_name, "name"), + GEOTAG(tt_cache_container, "container"), + GEOTAG(tt_cache_type, "type"), + GEOTAG(tt_cache_difficulty, "difficulty"), + GEOTAG(tt_cache_terrain, "terrain"), + GEOTAG(tt_cache_hint, "encoded_hints"), + GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG(tt_cache_desc_short, "short_description"), + GEOTAG(tt_cache_desc_long, "long_description"), + GEOTAG(tt_cache_placer, "owner"), + GEOTAG(tt_cache_favorite_points, "favorite_points"), + GEOTAG(tt_cache_personal_note, "personal_note"), + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt", {tt_cache_log_wpt, true}}, + {"/gpx/wpt/extensions/cache/logs/log/log_wpt", {tt_cache_log_wpt, true}}, + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type", {tt_cache_log_type, true}}, + {"/gpx/wpt/extensions/cache/logs/log/type", {tt_cache_log_type, true}}, + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date", {tt_cache_log_date, true}}, + {"/gpx/wpt/extensions/cache/logs/log/date", {tt_cache_log_date, true}}, + + {"/gpx/wpt/extensions", {tt_wpt_extensions, false}}, + + {GARMIN_WPT_EXT, {tt_garmin_wpt_extensions, false}}, + {GARMIN_WPT_EXT "/gpxx:Proximity", {tt_garmin_wpt_proximity, false}}, + {GARMIN_WPT_EXT "/gpxx:Temperature", {tt_garmin_wpt_temperature, false}}, + {GARMIN_TRKPT_EXT "/gpxtpx:atemp", {tt_garmin_wpt_temperature, true}}, + {GARMIN_WPT_EXT "/gpxx:Depth", {tt_garmin_wpt_depth, false}}, + {GARMIN_WPT_EXT "/gpxx:DisplayMode", {tt_garmin_wpt_display_mode, false}}, + {GARMIN_WPT_EXT "/gpxx:Categories", {tt_garmin_wpt_categories, false}}, + {GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", {tt_garmin_wpt_category, false}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", {tt_garmin_wpt_addr, false}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", {tt_garmin_wpt_city, false}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", {tt_garmin_wpt_state, false}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", {tt_garmin_wpt_country, false}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", {tt_garmin_wpt_postal_code, false}}, + {GARMIN_WPT_EXT "/gpxx:PhoneNumber", {tt_garmin_wpt_phone_nr, false}}, // In Garmin space, but in core of waypoint. - { tt_trk_trkseg_trkpt_heartrate, 1, GARMIN_TRKPT_EXT "/gpxtpx:hr" }, - { tt_trk_trkseg_trkpt_cadence, 1, GARMIN_TRKPT_EXT "/gpxtpx:cad" }, - - { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth" }, // in centimeters. - { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status" }, - - { tt_rte, 0, "/gpx/rte" }, - { tt_rte_name, 0, "/gpx/rte/name" }, - { tt_rte_desc, 0, "/gpx/rte/desc" }, - { tt_rte_url, 0, "/gpx/rte/url"}, /* GPX 1.0 */ - { tt_rte_urlname, 0, "/gpx/rte/urlname"}, /* GPX 1.0 */ - { tt_rte_link, 0, "/gpx/rte/link"}, /* GPX 1.1 */ - { tt_rte_link_text, 0, "/gpx/rte/link/text"}, /* GPX 1.1 */ - { tt_rte_link_type, 0, "/gpx/rte/link/type"}, /* GPX 1.1 */ - { tt_rte_number, 0, "/gpx/rte/number" }, - { tt_garmin_rte_display_color, 1, GARMIN_RTE_EXT "/gpxx:DisplayColor"}, - - { tt_rte_rtept, 0, "/gpx/rte/rtept" }, - - { tt_trk, 0, "/gpx/trk" }, - { tt_trk_name, 0, "/gpx/trk/name" }, - { tt_trk_desc, 0, "/gpx/trk/desc" }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg" }, - { tt_trk_url, 0, "/gpx/trk/url"}, /* GPX 1.0 */ - { tt_trk_urlname, 0, "/gpx/trk/urlname"}, /* GPX 1.0 */ - { tt_trk_link, 0, "/gpx/trk/link"}, /* GPX 1.1 */ - { tt_trk_link_text, 0, "/gpx/trk/link/text"}, /* GPX 1.1 */ - { tt_trk_link_type, 0, "/gpx/trk/link/type"}, /* GPX 1.1 */ - { tt_trk_number, 0, "/gpx/trk/number" }, - { tt_garmin_trk_display_color, 1, GARMIN_TRK_EXT "/gpxx:DisplayColor"}, - - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt" }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course" }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed" }, - - { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth" }, // in centimeters. + {GARMIN_TRKPT_EXT "/gpxtpx:hr", {tt_trk_trkseg_trkpt_heartrate, true}}, + {GARMIN_TRKPT_EXT "/gpxtpx:cad", {tt_trk_trkseg_trkpt_cadence, true}}, + + {"/gpx/wpt/extensions/h:depth", {tt_humminbird_wpt_depth, false}}, // in centimeters. + {"/gpx/wpt/extensions/h:status", {tt_humminbird_wpt_status, false}}, + + {"/gpx/rte", {tt_rte, false}}, + {"/gpx/rte/name", {tt_rte_name, false}}, + {"/gpx/rte/desc", {tt_rte_desc, false}}, + {"/gpx/rte/url", {tt_rte_url, false}}, /* GPX 1.0 */ + {"/gpx/rte/urlname", {tt_rte_urlname, false}}, /* GPX 1.0 */ + {"/gpx/rte/link", {tt_rte_link, false}}, /* GPX 1.1 */ + {"/gpx/rte/link/text", {tt_rte_link_text, false}}, /* GPX 1.1 */ + {"/gpx/rte/link/type", {tt_rte_link_type, false}}, /* GPX 1.1 */ + {"/gpx/rte/number", {tt_rte_number, false}}, + {GARMIN_RTE_EXT "/gpxx:DisplayColor", {tt_garmin_rte_display_color, true}}, + + {"/gpx/rte/rtept", {tt_rte_rtept, false}}, + + {"/gpx/trk", {tt_trk, false}}, + {"/gpx/trk/name", {tt_trk_name, false}}, + {"/gpx/trk/desc", {tt_trk_desc, false}}, + {"/gpx/trk/trkseg", {tt_trk_trkseg, false}}, + {"/gpx/trk/url", {tt_trk_url, false}}, /* GPX 1.0 */ + {"/gpx/trk/urlname", {tt_trk_urlname, false}}, /* GPX 1.0 */ + {"/gpx/trk/link", {tt_trk_link, false}}, /* GPX 1.1 */ + {"/gpx/trk/link/text", {tt_trk_link_text, false}}, /* GPX 1.1 */ + {"/gpx/trk/link/type", {tt_trk_link_type, false}}, /* GPX 1.1 */ + {"/gpx/trk/number", {tt_trk_number, false}}, + {GARMIN_TRK_EXT "/gpxx:DisplayColor", {tt_garmin_trk_display_color, true}}, + + {"/gpx/trk/trkseg/trkpt", {tt_trk_trkseg_trkpt, false}}, + {"/gpx/trk/trkseg/trkpt/course", {tt_trk_trkseg_trkpt_course, false}}, + {"/gpx/trk/trkseg/trkpt/speed", {tt_trk_trkseg_trkpt_speed, false}}, + + {"/gpx/trk/trkseg/trkpt/extensions/h:depth", {tt_humminbird_trk_trkseg_trkpt_depth, false}}, // in centimeters. /* Common to tracks, routes, and waypts */ -#define GPXWPTTYPETAG(type,passthrough,name) \ - {type, passthrough, "/gpx/wpt/" name }, \ - {type, passthrough, "/gpx/trk/trkseg/trkpt/" name }, \ - {type, passthrough, "/gpx/rte/rtept/" name } - - GPXWPTTYPETAG(tt_wpttype_ele, 0, "ele"), - GPXWPTTYPETAG(tt_wpttype_time, 0, "time"), - GPXWPTTYPETAG(tt_wpttype_geoidheight, 0, "geoidheight"), - GPXWPTTYPETAG(tt_wpttype_name, 0, "name"), - GPXWPTTYPETAG(tt_wpttype_cmt, 0, "cmt"), - GPXWPTTYPETAG(tt_wpttype_desc, 0, "desc"), - GPXWPTTYPETAG(tt_wpttype_url, 0, "url"), /* GPX 1.0 */ - GPXWPTTYPETAG(tt_wpttype_urlname, 0, "urlname"), /* GPX 1.0 */ - GPXWPTTYPETAG(tt_wpttype_link, 0, "link"), /* GPX 1.1 */ - GPXWPTTYPETAG(tt_wpttype_link_text, 0, "link/text"), /* GPX 1.1 */ - GPXWPTTYPETAG(tt_wpttype_link_type, 0, "link/type"), /* GPX 1.1 */ - GPXWPTTYPETAG(tt_wpttype_sym, 0, "sym"), - GPXWPTTYPETAG(tt_wpttype_type, 1, "type"), - GPXWPTTYPETAG(tt_wpttype_fix, 0, "fix"), - GPXWPTTYPETAG(tt_wpttype_sat, 0, "sat"), - GPXWPTTYPETAG(tt_wpttype_hdop, 0, "hdop"), - GPXWPTTYPETAG(tt_wpttype_vdop, 0, "vdop"), - GPXWPTTYPETAG(tt_wpttype_pdop, 0, "pdop"), - - {(tag_type)0, 0, nullptr} + GPXWPTTYPETAG("ele", tt_wpttype_ele, false), + GPXWPTTYPETAG("time", tt_wpttype_time, false), + GPXWPTTYPETAG("geoidheight", tt_wpttype_geoidheight, false), + GPXWPTTYPETAG("name", tt_wpttype_name, false), + GPXWPTTYPETAG("cmt", tt_wpttype_cmt, false), + GPXWPTTYPETAG("desc", tt_wpttype_desc, false), + GPXWPTTYPETAG("url", tt_wpttype_url, false), /* GPX 1.0 */ + GPXWPTTYPETAG("urlname", tt_wpttype_urlname, false), /* GPX 1.0 */ + GPXWPTTYPETAG("link", tt_wpttype_link, false), /* GPX 1.1 */ + GPXWPTTYPETAG("link/text", tt_wpttype_link_text, false), /* GPX 1.1 */ + GPXWPTTYPETAG("link/type", tt_wpttype_link_type, false), /* GPX 1.1 */ + GPXWPTTYPETAG("sym", tt_wpttype_sym, false), + GPXWPTTYPETAG("type", tt_wpttype_type, true), + GPXWPTTYPETAG("fix", tt_wpttype_fix, false), + GPXWPTTYPETAG("sat", tt_wpttype_sat, false), + GPXWPTTYPETAG("hdop", tt_wpttype_hdop, false), + GPXWPTTYPETAG("vdop", tt_wpttype_vdop, false), + GPXWPTTYPETAG("pdop", tt_wpttype_pdop, false), }; -// Maintain a fast mapping from full tag names to the struct above. - QHash hash; - QVector gpx_args = { { "snlen", &snlen, "Length of generated shortnames", -- 2.30.2